﻿using DataCapture.DeviceDataSave;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Timers;


namespace DataCapture.Helper;
/// <summary>
/// PLC处理帮助类
/// </summary>
public class PLCProcessingHelper
{
    

    private static ConcurrentDictionary<string, PLCDataBase> plcDictionary = new();
    private PublicHelp.AppSettings plAppSettings;
    private static readonly Lazy<PLCProcessingHelper> instance = new Lazy<PLCProcessingHelper>(() => new PLCProcessingHelper());
    public static PLCProcessingHelper Instance => instance.Value;

    // 是否处于睡眠状态
    private bool _isSleep;
    // 正常轮询间隔（秒）
    public int NormalInterval { get; set; } = 30;
    // 断电开始时间（24小时制，比如 22 = 22:00）
    public int PowerOffStartHour { get; set; } = 22;
    // 断电结束时间（24小时制，比如 6 = 06:00）
    public int PowerOffEndHour { get; set; } = 6;
    // 主轮询定时器（触发连接逻辑）
    private readonly Timer _pollTimer = new Timer();
   

    public PLCProcessingHelper()
    {
        plAppSettings = ConfigurationHelper.GetAppSettings;
        for (int i = 0; i < plAppSettings.PlcServer.Count; i++)
        {
            var plcServerConfig = plAppSettings.PlcServer[i];
           //启用PLC
            if (plcServerConfig.Enabled&&plcServerConfig.PlcType == "mitsubish")
            {//三菱PLC
                if (!plcDictionary.ContainsKey(plcServerConfig.PlcName))
                {

                    PLCDataBase plcDataBase = new PLCDataBase(plcServerConfig.PlcName,plcServerConfig.Ip,plcServerConfig.Port,plcServerConfig.PortList);
                    plcDictionary.TryAdd(plcServerConfig.PlcName, plcDataBase);
                }
            }
        }
        
        // 初始化定时器（默认按正常间隔，后续动态调整）
        _pollTimer.Interval = NormalInterval * 1000;
        _pollTimer.Elapsed += OnPollTimerElapsed;
        _pollTimer.AutoReset = true; // 自动重复触发
    }
    /// <summary>
    /// 获取PLC数据
    /// </summary>
    /// <param name="plcName"></param>
    /// <returns></returns>
    public PLCDataBase GetPLCDataBase(string plcName)
    {
        if (plcDictionary.TryGetValue(plcName, out PLCDataBase plcDataBase))
        {
            return plcDataBase;
        }
        else
        {
            return null; // 或者抛出异常
        }
    }


    // 定时器触发：执行轮询逻辑
    private async void OnPollTimerElapsed(object sender, ElapsedEventArgs e)
    {
        if (_isSleep)
        {
            if (!IsInPowerOffWindow())
            {//断电中断电结束，唤醒连接
                Log4NetHelper.Debug($"断电时段结束，尝试唤醒连接", true);

                WakeUpPLCDataBase();
                _isSleep = false;//退出睡眠

            }
            return;
        }
        // 1. 先预检测设备是否在线
        if (PingDeviceConnectCount()>0)
        {
            return;
        }
        Log4NetHelper.Debug($"所有设备不在线，跳过连接",true);
        // 2. 再判断是否在断电时段：是则跳过本次轮询
        if (!IsInPowerOffWindow())
        {
            return;
        }
        Log4NetHelper.Debug($"当前在断电时段（{PowerOffStartHour}:00~{PowerOffEndHour}:00），暂停轮询",true);
        SleepPLCDataBase();
        Log4NetHelper.Debug($"释放PLC连接资源", true);

    }

    // 判断当前是否在断电时段（处理跨天场景，比如 22:00~06:00）
    private bool IsInPowerOffWindow()
    {
        int currentHour = DateTime.Now.Hour;
        // 跨天场景（结束时间 < 开始时间，比如 22~6）
        if (PowerOffEndHour < PowerOffStartHour)
        {
            return currentHour >= PowerOffStartHour || currentHour < PowerOffEndHour;
        }
        // 非跨天场景（比如 08~12）
        else
        {
            return currentHour >= PowerOffStartHour && currentHour < PowerOffEndHour;
        }
    }
    /// <summary>
    /// 检测设备连接数量
    /// </summary>
    /// <returns></returns>
    public int  PingDeviceConnectCount()
    {
        int count = 0;
        for (int i = 0; i < plAppSettings.PlcServer.Count; i++)
        {
            var plcServerConfig = plAppSettings.PlcServer[i];
            if (plcServerConfig.Enabled)
            {
                if (plcDictionary.TryGetValue(plcServerConfig.PlcName, out PLCDataBase plcDataBase))
                {
                    if (plcDataBase._isConnected)
                    {
                        count++;
                    }
                }
            }
        }
        return count;
    }
    /// <summary>
    /// 唤醒PLC数据连接
    /// </summary>
    public void WakeUpPLCDataBase()
    {
        if (plcDictionary.Count > 0)
        {
            foreach (KeyValuePair<string, PLCDataBase> dataBase in plcDictionary)
            {

               dataBase.Value.InitializeConnection();//初始化连接
            }
        }
        Log4NetHelper.Debug($"唤醒PLC连接", true);

    }
    /// <summary>
    /// 催眠PLC数据连接
    /// </summary>
    public void SleepPLCDataBase()
    {
        _isSleep = true;//进入睡眠
        if (plcDictionary.Count > 0)
        {
            foreach (KeyValuePair<string, PLCDataBase> dataBase in plcDictionary)
            {
                dataBase.Value.Dispose();//初始化连接
            }
        }
        Log4NetHelper.Debug($"强制睡眠PLC连接", true);

    }
}